[SECTION .text]
global memcpy
global strcpy
global disp_str
global putchar
global disp_ret
global out_byte
global in_byte
global memset
global ipanic
global disable_int
global enable_int
global port_read
global port_write
; 内存复制函数：
; memcpy(void* dest, void* src, size_t sz)
memcpy:
    push esi
    push edi
    push ecx
    push ebx

    mov eax, [esp+28]
    mov esi, [esp+24]
    mov edi, [esp+20]
    xor edx , edx
    mov ebx, 4      ;打算一次4字节移动
    div ebx
    mov ecx, eax    ;结果，即有多少个双字
    test ecx, ecx
    jz .3
.1:
    lodsd 
    stosd
    loop .1
    mov ecx, edx    ;余数
    test ecx, ecx
    jz .3
.2:
    lodsb 
    stosb
    loop .2 
.3:
    pop ebx
    pop ecx
    pop edi
    pop esi

    ret
;memset(void* buff,u8 val, size_t sz)
memset:
    push edi
    push eax
    push ecx
    mov edi,[esp+16]
    mov al,[esp+20]
    mov ecx, [esp+24]
    test ecx, ecx
    jz .2
.1:
    stosb
    loop .1
.2:
    pop ecx
    pop eax
    pop edi
    ret

;strcpy(void* src, void* dest)
strcpy:
    push ebx
    mov esi, [esp+8]    ;src
    mov edi, [esp+12]   ;dest
    xor ebx, ebx
.start:
    lodsb
    stosb
    test al, al
    jz .end
    inc ebx
    jmp .start
.end:
    mov eax, ebx
    pop ebx
    ret

disp_ret:
    push eax
    push ebx

    mov eax, edi
    mov bl, 160
    div bl
    and eax, 0xff
    inc eax
    mov bl, 160
    mul bl
    mov edi, eax

    pop ebx
    pop eax
    ret

disp_str:
    push esi
    push edi
    push eax
    push ebx
    mov esi, [esp+0x14] ; 字符串首地址
    mov eax, [esp+0x18] ; x,y位置，颜色
    mov ecx, eax
    shr ecx, 0x10       ;颜色
    mov edi, eax
    and edi, 0xff
    shr eax, 0x8
    and eax, 0xff
    mov ebx, 80
    mul ebx 
    add edi, eax
    shl edi,1
    xor eax, eax
    mov ah, cl
    start:
        lodsb 
        test al, al
        jz end
        mov [gs:edi], ax
        add edi, 2
        jmp start ; 继续显示下一个
    end:          ; 显示完毕
        pop ebx
        pop eax
        pop edi
        pop esi
        ret

putchar:
    ret

out_byte:
    push eax
    push edx
    mov edx, [esp + 12]
    mov al, [esp + 16]

    out dx, al
    nop
    nop

    pop edx
    pop eax
    ret

in_byte:
    push edx
    mov edx, [esp+8]
    xor eax, eax
    in al, dx
    nop
    nop
    pop edx
    ret
; ========================================================================
;                  void port_read(u16 port, void* buf, int n);
; ========================================================================
port_read:
	mov	edx, [esp + 4]		; port
	mov	edi, [esp + 4 + 4]	; buf
	mov	ecx, [esp + 4 + 4 + 4]	; n
	shr	ecx, 1
	cld
	rep	insw
	ret

; ========================================================================
;                  void port_write(u16 port, void* buf, int n);
; ========================================================================
port_write:
	mov	edx, [esp + 4]		; port
	mov	esi, [esp + 4 + 4]	; buf
	mov	ecx, [esp + 4 + 4 + 4]	; n
	shr	ecx, 1
	cld
	rep	outsw
	ret

ipanic:
    int 0x03

disable_int:
    cli
    ret

enable_int:
    sti
    ret